package com.jzo2o.orders.manager.handler;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.jzo2o.api.trade.RefundRecordApi;
import com.jzo2o.api.trade.dto.response.ExecutionResultResDTO;
import com.jzo2o.common.constants.UserType;
import com.jzo2o.common.utils.BeanUtils;
import com.jzo2o.common.utils.CollUtils;
import com.jzo2o.common.utils.ObjectUtils;
import com.jzo2o.orders.base.enums.OrderRefundStatusEnum;
import com.jzo2o.orders.base.mapper.OrdersMapper;
import com.jzo2o.orders.base.model.domain.Orders;
import com.jzo2o.orders.base.model.domain.OrdersCanceled;
import com.jzo2o.orders.base.model.domain.OrdersRefund;
import com.jzo2o.orders.manager.model.dto.OrderCancelDTO;
import com.jzo2o.orders.manager.service.IOrdersRefundService;
import com.jzo2o.orders.manager.service.impl.OrdersCreateServiceImpl;
import com.jzo2o.orders.manager.service.impl.OrdersManagerServiceImpl;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

/**
 * @Author:on
 * @Description:订单定时任务
 * @Date Created in 2024-09-05-15:06
 * @Modified By:
 */
@Component
@Slf4j
public class OrdersHandler {
    @Resource
    private OrdersCreateServiceImpl ordersCreateService;
    @Resource
    private OrdersManagerServiceImpl ordersManagerService;
    @Resource
    private IOrdersRefundService ordersRefundService;
    @Resource
    private RefundRecordApi refundRecordApi;
    @Resource
    private OrdersMapper ordersMapper;

    /*
    * 自动取消支付超时的订单（超15分钟）
    * */
    @XxlJob(value = "cancelOverTimePayOrder")
    public void cancelOverTimePayOrder() {
        //查出支付超时的订单,假设一次拿一百条
        List<Orders> ordersList = ordersCreateService.queryOverTimePayOrdersListByCount(100);
        if (CollUtils.isEmpty(ordersList)){
            log.info("自动取消支付超时的订单，未查询到订单信息");
            return;
        }

        //遍历，调用订单取消的方法
        for (Orders orders : ordersList) {
            //取消订单
            OrderCancelDTO orderCancelDTO = BeanUtil.toBean(orders, OrderCancelDTO.class);
            orderCancelDTO.setCurrentUserType(UserType.SYSTEM);
            orderCancelDTO.setCancelReason("订单超时支付，自动取消");
            ordersManagerService.cancel(orderCancelDTO);
        }

    }

    /**
     * 订单退款异步任务
     */
    @XxlJob(value = "handleRefundOrders")
    public void handleRefundOrders(){
        //查询退款记录表
        List<OrdersRefund> ordersRefunds = ordersRefundService.queryRefundOrderListByCount(100);
        if (CollUtils.isEmpty(ordersRefunds)){
            log.info("退款定时任务，未查询到订单的退款记录");
            return;
        }
        //遍历退款记录，请求支付服务进行退款
        for (OrdersRefund ordersRefund : ordersRefunds) {
            //请求支付服务进行退款
            requestRefundOrder(ordersRefund);

        }


    }

    /**
     * 请求退款
     * @param ordersRefund 退款记录
     */
    public void requestRefundOrder(OrdersRefund ordersRefund){
        ExecutionResultResDTO executionResultResDTO=null;
        try {
            //请求支付服务退款
             executionResultResDTO = refundRecordApi.refundTrading(ordersRefund.getTradingOrderNo(), ordersRefund.getRealPayAmount());
        } catch (Exception e) {
            e.printStackTrace();
        }
        //解析退款结果,如果不是退款中更新订单的退款状态
        if (ObjectUtils.isNotNull(executionResultResDTO)&&executionResultResDTO.getRefundStatus()!= OrderRefundStatusEnum.REFUNDING.getStatus()){
            //更新订单退款状态
            refundOrder(ordersRefund,executionResultResDTO);
        }

    }


    /**
     * 更新退款状态
     * @param ordersRefund
     * @param executionResultResDTO
     */
    @Transactional(rollbackFor = Exception.class)
    public void refundOrder(OrdersRefund ordersRefund, ExecutionResultResDTO executionResultResDTO){
        //初始的订单状态为退款中
        Integer refundStatus =OrderRefundStatusEnum.REFUNDING.getStatus();

        if (executionResultResDTO.getRefundStatus()==OrderRefundStatusEnum.REFUND_SUCCESS.getStatus()){
            refundStatus=OrderRefundStatusEnum.REFUND_SUCCESS.getStatus();
        } else if (executionResultResDTO.getRefundStatus()==OrderRefundStatusEnum.REFUND_FAIL.getStatus()) {
            refundStatus=OrderRefundStatusEnum.REFUND_FAIL.getStatus();
        }
        //如果是退款中状态，程序结束
        if (ObjectUtil.equal(refundStatus, OrderRefundStatusEnum.REFUNDING.getStatus())) {
            return;
        }
        //sql: update orders set status=成功 where id=? and refund_status!=成功
        //sql: update orders set status=失败 where id=? and refund_status!=失败
        LambdaUpdateWrapper<Orders> updateWrapper = new LambdaUpdateWrapper<Orders>()
                .eq(Orders::getId, ordersRefund.getId())//订单id
                .ne(Orders::getRefundStatus, refundStatus)
                .set(Orders::getRefundStatus, refundStatus)
                .set(Orders::getRefundId, executionResultResDTO.getRefundId())
                .set(Orders::getRefundNo, executionResultResDTO.getRefundNo());

        //更新订单表
        int update = ordersMapper.update(null, updateWrapper);
        if (update>0){
            //清除退款记录
            ordersRefundService.removeById(ordersRefund.getId());
        }
    }

    //新启一个线程请求退款
    public void requestRefundNewThread(Long ordersRefundId){
        //启动一个线程请求第三方退款接口
        new Thread(()->{
            //查询退款记录
            OrdersRefund ordersRefund = ordersRefundService.getById(ordersRefundId);
            if(ObjectUtil.isNotNull(ordersRefund)){
                //请求退款
                requestRefundOrder(ordersRefund);
            }
        }).start();
    }

}
